<!--
 * @Author: your name
 * @Date: 2021-11-11 13:12:40
 * @LastEditTime: 2024-01-29 10:38:45
 * @LastEditors: swc
 * @Description: 
 * @FilePath: \wyJs\src\views\test\ruleEditor\components\codeEditor\index.vue
-->
<template>
  <div class="full-width-height">
    <textarea ref="codeEditor" class="init-container"></textarea>
  </div>
</template>
<script lang="ts">
import CodeMirror, { fromTextArea } from 'codemirror';
// import 'codemirror/lib/codemirror.css';
import './css/wyrule.css';

import 'codemirror/addon/selection/active-line';

import { T_srv, Tsrv, ts, ifs, regMode, vue } from './config';

@T_srv.comp
export default class T_codeEditor extends vue {
  @T_srv.prop({ required: true, type: Object }) config: object;

  private G_editor: any;

  created() {}

  mounted() {
    const self = this;
    const events = {
      editor: [
        'change',
        'changes',
        'beforeChange',
        'focus',
        'blur',
        'refresh',
        'update'
      ],
      doc: [
        'change',
        'renderLine',
        'delete',
        'clear', // 删除标记时触发。
        'hide' // 通过输入删除标记的最后一个字符时触发。]}
      ]
    };
    // 国际化方法传入mode
    regMode(CodeMirror, this.i18n);
    self.G_editor = CodeMirror.fromTextArea(
      this.$refs.codeEditor as HTMLTextAreaElement,
      this.config
    );

    for (const item of events.editor) {
      CodeMirror.on(self.G_editor, item, () => {
        // 在事件changes将国际化词打上标记
        if (item === 'changes') {
          this.markText();
        }
        self.$emit(`on-editor-${item}`, self.G_editor);
      });
    }
    for (const item of events.doc) {
      CodeMirror.on(self.G_editor.doc, item, () => {
        self.$emit(`on-doc-${item}`, self.G_editor.doc);
      });
    }
    this.$emit('on-mounted', this);
  }

  destroyed() {}

  // 国际化API
  i18n(key: string): string {
    // 取消国际化
    // const L_keys: string[] = [];
    // for (const ele of key.split(`.`)) {
    //   if (this.$te(`i18n.${ele}`)) {
    //     L_keys.push(Tsrv.getI18nByPath(`i18n.${ele}`).toString());
    //   } else {
    //     return ``;
    //   }
    // }
    // return L_keys.join(`.`);
    return '';
  }

  // 当前焦点处插入文本
  ins(text: string) {
    const L_pos = this.G_editor.getCursor();
    this.G_editor.replaceRange(text, L_pos);
  }

  // 将i18nValue 打标记显示 在editor changes 事件触发
  markText() {
    this.G_editor.doc.eachLine(line => {
      const L_currLine = this.G_editor.doc.getLineNumber(line);

      const L_tokens = this.G_editor.getLineTokens(L_currLine);
      L_tokens.forEach(ele => {
        // 如果需要国际化，此标识在mode tokenAttr里定义
        if (ele.state.isI18n) {
          const node = document
            .createRange()
            .createContextualFragment(
              `<i class ='cm-attribute' style = 'font-style:normal' title='${ele.state.i18nKeyValue}'>${ele.state.i18nValue}</i>`
            );
          let isMatch = false;
          // 相同位置是否有标记
          for (const mark of this.G_editor.doc.getAllMarks()) {
            const pos = mark.find();
            if (
              pos.from.line === L_currLine &&
              pos.from.ch === ele.start &&
              pos.to.ch === ele.end
            ) {
              isMatch = true;
              break;
            }
          }
          if (!isMatch) {
            this.G_editor.doc.markText(
              { line: L_currLine, ch: ele.start },
              { line: L_currLine, ch: ele.end },
              { replacedWith: node }
            );
          }
        }
      });
    });
  }
}
</script>
<style lang="scss" scoped>
.full-width-height ::v-deep .CodeMirror {
  height: 100%;
}
</style>
